//////////////////////////////////////////////////////////////////////////
//
// This file is a part of UKROP project.
// Copyright (c) Vladimir Gumenuk
//
// PROJECT:         Xort Custom Debug Engine
// FILE:            Process.cpp : Implementation of CProcess
// AUTHOR:          Vladimir Gumenuk
// DATE:            Dec-2012 -- Jan-2013
// MODIFICATIONS:
//
//////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Process.h"

// CProcess
CProcess::CProcess()
{
    ATLTRACE( "CProcess::CProcess()\n" );
    ZeroMemory( &m_pi, sizeof(m_pi) );
}

CProcess::~CProcess()
{
    ATLTRACE( "CProcess::~CProcess()\n" );
}

HRESULT CProcess::FinalConstruct()
{
    return S_OK;
}

void CProcess::FinalRelease()
{

}

STDMETHODIMP CProcess::GetInfo( PROCESS_INFO_FIELDS Fields, __RPC__out PROCESS_INFO *pProcessInfo )
{
    ATLTRACE( "CProcess::GetInfo()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::EnumPrograms( __RPC__deref_out_opt IEnumDebugPrograms2 **ppEnum )
{
    ATLTRACE( "CProcess::EnumPrograms()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::GetName( GETNAME_TYPE gnType, __RPC__deref_out_opt BSTR *pbstrName )
{
    ATLTRACE( "CProcess::GetName()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::GetServer( __RPC__deref_out_opt IDebugCoreServer2 **ppServer )
{
    ATLTRACE( "CProcess::GetServer()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::Terminate()
{
    if( m_pi.hProcess )
    {
        TerminateProcess( m_pi.hProcess, 0 );
        m_pi.hProcess = NULL;
    }
    return S_OK;
}

STDMETHODIMP CProcess::Attach( __RPC__in_opt IDebugEventCallback2 *pCallback, GUID *rgguidSpecificEngines, DWORD celtSpecificEngines, HRESULT *rghrEngineAttach )
{
    ATLTRACE( "CProcess::Attach()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::CanDetach()
{
    ATLTRACE( "CProcess::CanDetach()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::Detach()
{
    ATLTRACE( "CProcess::Detach()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::GetPhysicalProcessId( __RPC__out AD_PROCESS_ID *pProcessId )
{
    if( !pProcessId )
        return E_POINTER;
    
    pProcessId->ProcessId.dwProcessId = m_pi.dwProcessId; //GetCurrentProcessId();
    pProcessId->ProcessIdType         = AD_PROCESS_ID_SYSTEM;
    return S_OK;
}

STDMETHODIMP CProcess::GetProcessId( __RPC__out GUID *pguidProcessId )
{
    if( !pguidProcessId )
        return E_POINTER;
    *pguidProcessId = IID_XortVirtualProcess; // virtual machine process :)
    return S_OK;
}

STDMETHODIMP CProcess::GetAttachedSessionName( __RPC__deref_out_opt BSTR *pbstrSessionName )
{
    ATLTRACE( "CProcess::GetAttachedSessionName()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::EnumThreads( __RPC__deref_out_opt IEnumDebugThreads2 **ppEnum )
{
    ATLTRACE( "CProcess::EnumThreads()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::CauseBreak()
{
    ATLTRACE( "CProcess::CauseBreak()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::GetPort( __RPC__deref_out_opt IDebugPort2 **ppPort )
{
    ATLTRACE( "CProcess::GetPort()\n" );
    return E_NOTIMPL;
}

STDMETHODIMP CProcess::LaunchExecutable( LPCOLESTR lpszExeFilePath )
{
    STARTUPINFOW sti;
    ZeroMemory( &sti, sizeof( sti ) );
    sti.cb = sizeof( STARTUPINFOW );

    CComBSTR bsCmdLine = L"\"";
    bsCmdLine += lpszExeFilePath;
    bsCmdLine += L"\"";
    BOOL bOk = CreateProcessW( lpszExeFilePath, bsCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &sti, &m_pi );

    return bOk ? S_OK : E_FAIL;
}
